package com.beiben.statistics;

import com.beiben.statistics.vo.*;
import com.beiben.utils.DateUtil;
import com.ruoyi.common.utils.Arith;
import com.ruoyi.common.utils.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

/**
 * Created by admin on 2020/12/21.
 */
public class ServiceUtils {

    /*
     * 设置默认查询天数（默认30天）
     * */
    public static void setSearchTime(RecordSearchParamVo recordSearchParamVo) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (StringUtils.isEmpty(recordSearchParamVo.getBeginTime()) || StringUtils.isEmpty(recordSearchParamVo.getEndTime())) {
            recordSearchParamVo.setBeginTime(sdf.format(new Date()));
            String date = DateUtil.getDatePoorDay(new Date(), -29, "yyyy-MM-dd");//默认30天
            recordSearchParamVo.setEndTime(date);
        }
    }

    /*
     * 计算时间参数
     * */
    public static List<NameValueVo> resultList(RecordSearchParamVo recordSearchParamVo, List<WorkItemVo> list) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<NameValueVo> resultList = null;
        if (StringUtils.isNotEmpty(recordSearchParamVo.getBeginTime()) && StringUtils.isNotEmpty(recordSearchParamVo.getEndTime())) {
            Date endTime = sdf.parse(recordSearchParamVo.getEndTime());
            Date beginTime = sdf.parse(recordSearchParamVo.getBeginTime());
            for (WorkItemVo wiv : list) {
                long startday = DateUtil.getDatePoorDay(wiv.getStartTime(), beginTime);//实际开始时间-查询开始时间
                long endday = DateUtil.getDatePoorDay(wiv.getFinishTime(), endTime);//实际结束时间-查询结束时间
                long relTime = DateUtil.getDatePoorDay(wiv.getFinishTime(), wiv.getStartTime()) + 1;
                if (startday < 0 && endday > 0) {//外包含
                    long searchTime = DateUtil.getDatePoorDay(endTime, beginTime) + 1;
                    Double relTotal = Arith.mul(Arith.div(wiv.getTotal(), relTime, 2), searchTime);
                    wiv.setTotal(relTotal);
                } else if (startday < 0 && endday <= 0) {//左包含
                    long searchTime = DateUtil.getDatePoorDay(wiv.getFinishTime(), beginTime) + 1;
                    Double relTotal = Arith.mul(Arith.div(wiv.getTotal(), relTime, 2), searchTime);
                    wiv.setTotal(relTotal);
                } else if (startday >= 0 && endday > 0) {//右包含
                    long searchTime = DateUtil.getDatePoorDay(endTime, wiv.getStartTime()) + 1;
                    Double relTotal = Arith.mul(Arith.div(wiv.getTotal(), relTime, 2), searchTime);
                    wiv.setTotal(relTotal);
                }
            }
            resultList = groupDept(list);
        } else {
            resultList = groupDept(list);
        }
        resultList.sort(Comparator.comparing(NameValueVo::getValue).reversed());
        return resultList;
    }

    /*
  * 按组织机构名称分组
  * */
    public static List<NameValueVo> groupDept(List<WorkItemVo> list) {
        List<NameValueVo> resultList = new ArrayList<NameValueVo>();
        Map<String, List<WorkItemVo>> map = list.stream().collect(Collectors.groupingBy(b -> b.getName()));
        for (String key : map.keySet()) {
            List<WorkItemVo> wList = map.get(key);
            NameValueVo nameValueVo = new NameValueVo();
            Double total = 0.0;
            for (WorkItemVo wiv : wList) {
                total = Arith.add(total, wiv.getTotal());
                nameValueVo.setHours(wiv.getHours());
            }
            nameValueVo.setValue(total);
            nameValueVo.setName(key);
            nameValueVo.setId(String.valueOf(wList.get(0).getId()));
            resultList.add(nameValueVo);
        }
        return resultList;
    }

    /*
 * 按组织机构名称分组
 * */
    public static List<CompositeDateVo> groupCvDept(List<CompositeDateVo> list,String type) {
        List<CompositeDateVo> resultList = new ArrayList<CompositeDateVo>();
        Map<String, List<CompositeDateVo>> map = null;
        if("time".equals(type)){
            map = list.stream().collect(Collectors.groupingBy(b -> b.getTime()));
        }else{
            map = list.stream().collect(Collectors.groupingBy(b -> b.getName()));
        }
        for (String key : map.keySet()) {
            List<CompositeDateVo> wList = map.get(key);
            CompositeDateVo cv = new CompositeDateVo();
            Double total = 0.0;
            Double workValue = 0.0;
            Double projectValue = 0.0;
            Double hours = 0.0;
            Long userId = null;
            for (CompositeDateVo wiv : wList) {
                total = Arith.add(total,Arith.add(wiv.getProjectValue(), wiv.getWorkValue()));
                workValue =  Arith.add(workValue, wiv.getWorkValue());
                projectValue =  Arith.add(projectValue, wiv.getProjectValue());
                if(null!=wiv.getHours()){
                    hours = wiv.getHours();
                }
                if(null!=wiv.getUserId()){
                    userId = wiv.getUserId();
                }
            }
            cv.setTotalValue(total);
            cv.setWorkValue(workValue);
            cv.setProjectValue(projectValue);
            if("time".equals(type)){
                cv.setTime(key);
                cv.setName(String.valueOf(wList.get(0).getName()));
            }else{
                cv.setName(key);
                cv.setTime(null);
            }
            cv.setHours(hours);
            cv.setUserId(userId);
            cv.setId(String.valueOf(wList.get(0).getId()));
            resultList.add(cv);
        }
        return resultList;
    }


    public static  List<CompositeDateVo> nvChangeCv(List<CompositeDateVo>  comResultList,RecordSearchParamVo recordSearchParamVo, List<WorkItemVo> everyDay, List<WorkItemVo> project)throws ParseException{
        List<NameValueVo> everyDayResultList = resultList(recordSearchParamVo, everyDay);
        List<NameValueVo> projectResultList = resultList(recordSearchParamVo, project);
        for(NameValueVo ev : everyDayResultList){
            CompositeDateVo cv = new CompositeDateVo();
            cv.setId(ev.getId());
            cv.setName(ev.getName());
            cv.setWorkValue(ev.getValue());
            cv.setProjectValue(0.0);
            cv.setHours(ev.getHours());
            comResultList.add(cv);
        }
        for(NameValueVo ev : projectResultList){
            CompositeDateVo cv = new CompositeDateVo();
            cv.setId(ev.getId());
            cv.setName(ev.getName());
            cv.setProjectValue(ev.getValue());
            cv.setWorkValue(0.0);
            cv.setHours(ev.getHours());
            comResultList.add(cv);
        }
        comResultList = ServiceUtils.groupCvDept(comResultList,"name");
        comResultList.sort(Comparator.comparing(CompositeDateVo::getTotalValue).reversed());
        return comResultList;
    }

    /*
    * 用于线行数据转换
    * */
    public static List<CompositeDateVo> lvChangeCv(List<LineDataVo> workList,List<LineDataVo> projectList){
        List<CompositeDateVo>  comResultList = new CopyOnWriteArrayList<>();
        for(LineDataVo lv : workList){
            CompositeDateVo cv = new CompositeDateVo();
            cv.setUserId(lv.getUserId());
            cv.setTime(lv.getTime());
            cv.setName(lv.getName());
            cv.setWorkValue(lv.getValue());
            cv.setProjectValue(0.0);
            comResultList.add(cv);
        }
        for(LineDataVo lv : projectList){
            CompositeDateVo cv = new CompositeDateVo();
            cv.setUserId(lv.getUserId());
            cv.setTime(lv.getTime());
            cv.setName(lv.getName());
            cv.setProjectValue(lv.getValue());
            cv.setWorkValue(0.0);
            comResultList.add(cv);
        }
        return  ServiceUtils.groupCvDept(comResultList,"time");
    }
    /*
    * 计算曲线日期，默认查询当期日期近30天的时间，如果有查询条件则查询从开始时间算近30天的日期
    * */
    public static void setLineSearchTime(RecordSearchParamVo recordSearchParamVo) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (StringUtils.isNotEmpty(recordSearchParamVo.getBeginTime()) || StringUtils.isNotEmpty(recordSearchParamVo.getEndTime())) {
            Date beginTime = sdf.parse(recordSearchParamVo.getBeginTime());
            String date = DateUtil.getDatePoorDay(beginTime, -29, "yyyy-MM-dd");//默认30天
            recordSearchParamVo.setEndTime(date);
        } else {
            ServiceUtils.setSearchTime(recordSearchParamVo);
        }
    }
}
